import moment from 'moment';
import { isArray } from 'util';
// @ts-ignore
import type { RangePickerValue } from 'antd/lib/date-picker/interface';

export enum NO_UNIT {
  MILLI_SEC,
  SEC,
  MIN,
  HOUR,
  DAY,
  WEEK,
  MONTH,
  QUARTER,
  YEAR,
}

export function getTimeDistance(
  type: 'today' | 'week' | 'month' | 'year',
): [ moment.Moment, moment.Moment ] {
  const now = new Date();

  if (type === 'today') {
    return [ moment(now).startOf('date'), moment(now).endOf('date').add(1, 'seconds') ];
  }

  if (type === 'week') {
    return [ moment(now).startOf('week'), moment(now).endOf('week').add(1, 'seconds') ];
  }

  if (type === 'month') {
    return [ moment(now).startOf('month'), moment(now).endOf('month').add(1, 'seconds') ];
  }

  return [ moment(now).startOf('year'), moment(now).endOf('year').add(1, 'seconds') ];
}


export function getTimeDatePickerDistance(
  type: 'today' | 'week' | 'month' | 'year',
): [ moment.Moment, moment.Moment ] {
  const now = new Date();

  if (type === 'today') {
    return [ moment(now).startOf('date'), moment(now).endOf('date') ];
  }

  if (type === 'week') {
    return [ moment(now).startOf('week'), moment(now).endOf('week') ];
  }

  if (type === 'month') {
    return [ moment(now).startOf('month'), moment(now).endOf('month') ];
  }

  return [ moment(now).startOf('year'), moment(now).endOf('year') ];
}

export function getTimeDatePickerDistanceAdd(
  type: 'today' | 'week' | 'month' | 'year',
): [ moment.Moment, moment.Moment ] {
  const now = new Date();

  if (type === 'today') {
    return [ moment(now).startOf('date'), moment(now).endOf('date') ];
  }

  if (type === 'week') {
    return [ moment(now).startOf('week'), moment(now).endOf('week').add(1, 'seconds') ];
  }

  if (type === 'month') {
    return [ moment(now).startOf('month'), moment(now).endOf('month') ];
  }

  return [ moment(now).startOf('year'), moment(now).endOf('year') ];
}

const map: Record<number, { unit: 'month' | 'day' | 'hour'; format: string }> = {
  [NO_UNIT.MONTH]: { unit: 'month', format: 'YYYY年MM月' },
  [NO_UNIT.DAY]: { unit: 'day', format: 'DD日' },
  [NO_UNIT.HOUR]: { unit: 'hour', format: 'HH时' },
};

/**
 * 根据时间跨度自动判断应该选取的时间单位
 * @param range 时间跨度
 * @param expected 期望获取的单位选定
 * @return 若没有指定 @param expected 则直接返回判断的单位 否则从期望的单位中选取与结果最相似的单位返回
 */
export function getTimeRangeUnit(
  range: [ moment.Moment, moment.Moment ],
  expected?: NO_UNIT[],
): { unit: 'month' | 'day' | 'hour'; format: string } {
  const diff = moment.duration(range[1].diff(range[0]));

  // 根据时间差来获取单位
  let unit: NO_UNIT;
  if (diff.asMilliseconds() < 3000) {
    unit = NO_UNIT.MILLI_SEC;
  } else if (diff.asSeconds() < 61) {
    unit = NO_UNIT.SEC;
  } else if (diff.asMinutes() < 61) {
    unit = NO_UNIT.MIN;
  } else if (diff.asHours() < 25) {
    unit = NO_UNIT.HOUR;
  } else if (diff.asDays() < 32) {
    unit = NO_UNIT.DAY;
  } else if (diff.asWeeks() < 27) {
    unit = NO_UNIT.WEEK;
  } else if (diff.asMonths() < 37) {
    unit = NO_UNIT.MONTH;
  } else if (diff.asMonths() < 49) {
    unit = NO_UNIT.QUARTER;
  } else {
    unit = NO_UNIT.YEAR;
  }

  let rst: NO_UNIT;

  if (!isArray(expected) || expected.length === 0 || expected.includes(unit)) {
    // 若没有指定期望的单位 则直接返回判断的单位
    rst = unit;
  } else {
    // 否则从期望的单位中选取与结果最相似的单位返回
    const sorted = [ ...expected, unit ].sort((a, b) => a - b);
    const unitIndex = sorted.indexOf(unit);
    if (unitIndex === 0) {
      rst = sorted[unitIndex + 1];
    } else if (unitIndex === sorted.length - 1) {
      rst = sorted[unitIndex - 1];
    } else {
      const preDiff = unit - sorted[unitIndex - 1];
      const nxtDiff = sorted[unitIndex + 1] - unit;
      if (preDiff <= nxtDiff) rst = sorted[unitIndex - 1];
      else rst = sorted[unitIndex + 1];
    }
  }

  return map[rst];
}

export function rangePickerValueFomatter(rangePickerValue: RangePickerValue): [ moment.Moment, moment.Moment ] {
  const now = moment(Date.now());
  const start = rangePickerValue[0] || now;
  const end = rangePickerValue[1] || now;
  return start.isBefore(end) ? [ start, end ] : [ end, start ];
}


export const DateFormat = (microSecond: number) => {
  // 总秒数
  const second = Math.floor(microSecond / 1000);
  // 天数
  const day = Math.floor(second / 3600 / 24);
  // 小时
  const hr = Math.floor(second / 3600 % 24);
  // 分钟
  const min = Math.floor(second / 60 % 60);
  // 秒
  const sec = Math.floor(second % 60);
  if (day !== 0) {
    return `${ day }天${ hr }小时${ min }分钟${ sec }秒`;
  }
  if (hr !== 0) {
    return `${ hr }小时${ min }分钟${ sec }秒`;
  }
  if (min !== 0) {
    return `${ min }分钟${ sec }秒`;
  }
  return `${ sec }秒`;

};
